package br.com.sovi.resources.ponto;

import java.util.List;

import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.openinsula.vulcano.core.command.invoker.CommandInvoker;
import org.openinsula.vulcano.orm.command.factory.CommandFactory;
import org.openinsula.vulcano.orm.dao.query.DaoQuery;
import org.openinsula.vulcano.orm.dao.query.builder.DaoSelect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import br.com.sovi.persistence.Dispositivo;
import br.com.sovi.persistence.Ponto;
import br.com.sovi.resources.FindDispositivoBySerialCommand;
import br.com.sovi.utils.DateTimeUtils;

@Component
@Path("/ponto")
@Produces(MediaType.APPLICATION_JSON)
public class PontoResource {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private CommandInvoker commandInvoker;

	@POST
	@Path("/add")
	public Object recordPoint(@FormParam("dispositivo") final String serial,
			@FormParam("pontos") final List<PontoVO> pontos) throws JSONException {
		logger.debug("Gravando novo ponto.");
		logger.debug("Serial do Dispositivo: " + serial);
		logger.debug("Pontos recebidos: " + pontos.size());

		try {
			commandInvoker.invoke(new RecordPointCommand(serial, pontos));
			return new JSONObject().append("success", "Pontos gravados com sucesso.");
		}
		catch (Exception e) {
			return new JSONObject().append("error", e.getMessage());
		}
	}

	@GET
	@Path("/findByEmpresaAndData")
	public List<PontoVO> findPointsByEmpresaAndData(@QueryParam("dispositivo") final String serial,
			@QueryParam("dataInicial") final String dataInicial, @QueryParam("dataFinal") final String dataFinal) {
		logger.debug("Capturando pontos por dispositivo e data.");
		logger.debug("Dispositivo recebida: " + serial);
		logger.debug("Data Inicial recebida: " + dataInicial);
		logger.debug("Dispositivo recebida: " + dataFinal);

		List<Ponto> pontos = commandInvoker.invoke(new FindPontosByEmpresaAndData(serial, DateTimeUtils
				.parseDate(dataInicial), DateTimeUtils.parseDate(dataFinal)));

		return PontoVO.convertList(pontos);
	}

	@GET
	@Path("/ultimoFromDispositivo")
	public PontoVO getUltimoFromDispositivo(@QueryParam("dispositivo") final String serial) throws JSONException {
		logger.debug("Gravando novo ponto.");
		logger.debug("Serial do Dispositivo: " + serial);

		Dispositivo dispositivo = commandInvoker.invoke(new FindDispositivoBySerialCommand(serial));

		DaoQuery<Ponto> query2 = new DaoSelect<Ponto>().all().from(Ponto.class).eq("dispositivo", dispositivo).order(
				"data desc").limit(1).toQuery();
		Ponto ponto = commandInvoker.invoke(CommandFactory.newFindUnique(query2));

		if (ponto != null) {
			return new PontoVO(ponto);
		}
		else {
			return null;
		}
	}

}
